from celery import shared_task
from django.db.models import Count, Avg, Sum, F, Q, IntegerField, Value
from django.db.models.functions import TruncDate, Coalesce, Cast
from datetime import datetime, timedelta
from collections import Counter
import pandas as pd
import numpy as np
from .models import Report
from data_crawler.models import CrawledData
import logging
import jieba
import jieba.analyse

logger = logging.getLogger(__name__)

@shared_task
def generate_report_task(report_id):
    try:
        logger.info(f"Starting report generation for report_id: {report_id}")
        report = Report.objects.get(id=report_id)
        
        # 获取数据源的数据
        queryset = CrawledData.objects.filter(
            task__data_source=report.data_source,
            created_at__date__range=[report.start_date, report.end_date]
        )
        logger.info(f"Found {queryset.count()} records for analysis")
        
        result = {}
        
        # 数据量趋势
        if 'data_volume' in report.metrics:
            logger.info("Generating data volume analysis")
            data_volume = queryset.annotate(
                date=TruncDate('created_at')
            ).values('date').annotate(
                count=Count('id')
            ).order_by('date')
            
            result['data_volume'] = {
                'dates': [item['date'].strftime('%Y-%m-%d') for item in data_volume],
                'values': [item['count'] for item in data_volume]
            }
        
        # 互动分析
        if 'engagement' in report.metrics:
            logger.info("Generating engagement analysis")
            engagement = queryset.annotate(
                date=TruncDate('created_at')
            ).values('date').annotate(
                comments=Coalesce(Cast('data__post__engagement__comments', output_field=IntegerField()), Value(0)),
                likes=Coalesce(Cast('data__post__engagement__likes', output_field=IntegerField()), Value(0)),
                reposts=Coalesce(Cast('data__post__engagement__reposts', output_field=IntegerField()), Value(0))
            ).order_by('date')
            
            result['engagement'] = {
                'dates': [item['date'].strftime('%Y-%m-%d') for item in engagement],
                'comments': [item['comments'] for item in engagement],
                'likes': [item['likes'] for item in engagement],
                'reposts': [item['reposts'] for item in engagement]
            }
        
        # 用户活跃度
        if 'user_activity' in report.metrics:
            logger.info("Generating user activity analysis")
            user_activity = queryset.annotate(
                date=TruncDate('created_at')
            ).values('date').annotate(
                active_users=Count('data__user__id', distinct=True)
            ).order_by('date')
            
            result['user_activity'] = {
                'dates': [item['date'].strftime('%Y-%m-%d') for item in user_activity],
                'values': [item['active_users'] for item in user_activity]
            }
        
        # 内容分析
        if 'content_analysis' in report.metrics:
            logger.info("Generating content analysis")
            texts = queryset.values_list('data__post__content', flat=True)
            
            keywords = []
            for text in texts:
                if text:
                    try:
                        keywords.extend(jieba.analyse.extract_tags(text, topK=5))
                    except Exception as e:
                        logger.error(f"Error extracting keywords from text: {e}")
            
            keyword_counter = Counter(keywords)
            top_keywords = keyword_counter.most_common(10)
            
            result['content_analysis'] = {
                'topics': [{'name': k, 'value': v} for k, v in top_keywords]
            }
        
        # 情感分析
        if 'sentiment' in report.metrics:
            logger.info("Generating sentiment analysis")
            sentiment_counts = queryset.values('data__post__sentiment').annotate(
                count=Count('id')
            )
            
            result['sentiment'] = {
                'positive': next((item['count'] for item in sentiment_counts if item['data__post__sentiment'] == 'positive'), 0),
                'neutral': next((item['count'] for item in sentiment_counts if item['data__post__sentiment'] == 'neutral'), 0),
                'negative': next((item['count'] for item in sentiment_counts if item['data__post__sentiment'] == 'negative'), 0)
            }
        
        logger.info("Report generation completed successfully")
        report.result = result
        report.status = 'completed'
        report.save()
        
    except Exception as e:
        logger.error(f"Error generating report: {str(e)}")
        if report:
            report.status = 'failed'
            report.error_message = str(e)
            report.save()
        raise 